<?php

declare(strict_types=1);

namespace app\controller\system\order;

use app\BaseController;
use app\model\Shipment as ShipmentModel;
use app\service\factory\ResponseFactory;
use app\service\order\ShipmentService;
use app\validate\order\ShipmentValidate;
use InvalidArgumentException;
use think\Response;
use Throwable;

class Pickup extends BaseController
{
    public function index(ShipmentService $shipmentService): Response
    {
        try {
            $page = max(1, (int) $this->request->param('page', 1));
            $pageSize = (int) $this->request->param('page_size', 20);
            $pageSize = $pageSize > 0 ? min($pageSize, 100) : 20;

            $filters = $this->request->only([
                'keyword',
                'status',
                'order_id',
                'seller_org_id',
                'buyer_org_id',
                'company_id',
            ], 'get');

            $statusParam = $filters['status'] ?? null;
            if ($statusParam === null || $statusParam === '') {
                $filters['status'] = ShipmentModel::STATUS_PENDING_PICKUP;
            } elseif ($statusParam === 'all') {
                unset($filters['status']);
            } else {
                $filters['status'] = (int) $statusParam;
            }

            $paginator = $shipmentService->paginate($filters, $page, $pageSize);
            $list = $shipmentService->formatCollection($paginator->items());

            return json(ResponseFactory::paginated(
                $list,
                (int) $paginator->total(),
                $page,
                $pageSize
            ));
        } catch (Throwable $e) {
            return json(ResponseFactory::error($e->getMessage(), $e->getCode() ?: 500));
        }
    }

    public function read(int $id, ShipmentService $shipmentService): Response
    {
        try {
            $shipment = $shipmentService->findById($id);
            if (!$shipment) {
                return json(ResponseFactory::error('揽件任务不存在', 404));
            }

            return json(ResponseFactory::success($shipmentService->format($shipment)));
        } catch (Throwable $e) {
            return json(ResponseFactory::error($e->getMessage(), $e->getCode() ?: 500));
        }
    }

    public function update(int $id, ShipmentService $shipmentService): Response
    {
        try {
            $shipment = ShipmentModel::find($id);
            if (!$shipment) {
                return json(ResponseFactory::error('揽件任务不存在', 404));
            }

            $payload = $this->request->put();
            $payload['id'] = $id;

            $this->validate($payload, ShipmentValidate::class . '.update');

            $updated = $shipmentService->update($shipment, $payload);

            return json(ResponseFactory::success(
                $shipmentService->format($updated),
                '揽件任务已更新'
            ));
        } catch (InvalidArgumentException $e) {
            return json(ResponseFactory::error($e->getMessage(), 422));
        } catch (Throwable $e) {
            return json(ResponseFactory::error($e->getMessage(), $e->getCode() ?: 500));
        }
    }
}
